#include <QPainter>
#include <QTimerEvent>
#include <QMessageBox>
#include <QKeyEvent>
#include "mainwindow.h"
#include "block.h"

MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
{
    int w = AREA_COL * BLOCK_SIZE + MARGIN * 2 + 4 * BLOCK_SIZE + MARGIN;
    int h = AREA_ROW * BLOCK_SIZE + MARGIN * 2;
    setFixedSize(w, h);
    setWindowTitle("俄罗斯方块");

    initGame();
}

void MainWindow::initGame()
{
    for(int i=0;i<AREA_ROW;i++)
        for(int j=0;j<AREA_COL;j++)
            game_area[i][j]=0;

    speed_ms=800;

    //分数清0
    score=0;

    //开始游戏
    startGame();
}

void MainWindow::startGame()
{
    game_timer=startTimer(speed_ms); //开启游戏timer

    //产生第一个方块和下一个方块
    currentBlock = Block::newRandomBlock(game_area);
    nextBlock = Block::newRandomBlock(game_area);
}

void MainWindow::gameOver()
{
    //游戏结束停止计时器
    killTimer(game_timer);

    delete currentBlock;
    delete nextBlock;

    QMessageBox::information(this,"failed","game over");
}

void MainWindow::blockMove(Motion motion)
{
    switch (motion) {
    case Rotate:
        currentBlock->moveRotate();
        break;
    case MoveDown:
        if(currentBlock->moveDown())
            break;

        // 不能下移了就固定在场景中
        currentBlock->putDown();

        // 消除底部完成的行
        clearCompleteLine();

        // 检查是否游戏结束
        if(!checkGameOver()){
            delete currentBlock;
            currentBlock = nextBlock;
            nextBlock = Block::newRandomBlock(game_area);
        }
        break;
    case MoveLeft:
        currentBlock->moveLeft();
        break;
    case MoveRight:
        currentBlock->moveRight();
        break;
    case DropDown: //一次到底
        //一格一格下移，直到不能下移
        while(currentBlock->moveDown())
            ;

        // 不能下移了就固定在场景中
        currentBlock->putDown();

        // 消除底部完成的行
        clearCompleteLine();

        // 检查是否游戏结束
        if(!checkGameOver()){
            delete currentBlock;
            currentBlock = nextBlock;
            nextBlock = Block::newRandomBlock(game_area);
        }
        break;
    default:
        break;
    }

    update();
}

void MainWindow::clearCompleteLine()
{
    //处理消行，整个场景上面的行依次下移
    int i = AREA_ROW-1;
    int line_count = 0; //记消行数
    while(i >= 1)
    {
        bool is_line_full = true;
        for(int j = 0; j < AREA_COL; j++)
            if(game_area[i][j]==0)
            {
                is_line_full=false;
                i--;
                break;
            }
        if(is_line_full)
        {
            for(int k = i; k >= 1; k--)
                for(int j = 0; j < AREA_COL; j++)
                    game_area[k][j] = game_area[k-1][j];
            line_count++; //每次增加消行的行数
        }
    }
    score+=line_count*10; //得分
}

bool MainWindow::checkGameOver()
{
    //判断游戏是否结束
    for(int j = 0; j < AREA_COL; j++)
        if(game_area[0][j]==2) //最顶端也有稳定方块
        {
            gameOver();
            return true;
        }
    return false;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);

    // 画游戏场景边框
    painter.setBrush(QBrush(Qt::white, Qt::SolidPattern));
    painter.drawRect(MARGIN, MARGIN, AREA_COL * BLOCK_SIZE, AREA_ROW * BLOCK_SIZE);

    //画方块预告
    painter.setBrush(QBrush(Qt::blue,Qt::SolidPattern));
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(nextBlock->block[i][j]==1)
                painter.drawRect(MARGIN*3+AREA_COL*BLOCK_SIZE+j*BLOCK_SIZE,MARGIN+i*BLOCK_SIZE,BLOCK_SIZE,BLOCK_SIZE);

    //绘制得分
    painter.setPen(Qt::black);
    painter.setFont(QFont("Arial",14));
    painter.drawText(QRect(MARGIN*3+AREA_COL*BLOCK_SIZE,MARGIN*2+4*BLOCK_SIZE,BLOCK_SIZE*4,BLOCK_SIZE*4),Qt::AlignCenter,"score: "+QString::number(score));

    //绘制下落方块和稳定方块,注意方块边线的颜色是根据setPen来的，默认黑色
    for(int i=0;i<AREA_ROW;i++)
        for(int j=0;j<AREA_COL;j++)
        {
            //绘制稳定方块
            if(game_area[i][j]==2)
            {
                painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));
                painter.drawRect(j*BLOCK_SIZE+MARGIN,i*BLOCK_SIZE+MARGIN,BLOCK_SIZE,BLOCK_SIZE);
            }
        }
    for(int i = 0; i < 4; i ++)
        for(int j = 0; j < 4; j ++){
            if(currentBlock->block[i][j] == 1){
                painter.setBrush(QBrush(Qt::red,Qt::SolidPattern));
                int x = j + currentBlock->position.x;
                int y = i + currentBlock->position.y;
                painter.drawRect(x*BLOCK_SIZE+MARGIN,y*BLOCK_SIZE+MARGIN,BLOCK_SIZE,BLOCK_SIZE);
            }
        }
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    //方块下落
    if(event->timerId()==game_timer)
        blockMove(MoveDown);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    switch(event->key())
    {
    case Qt::Key_Up:
        blockMove(Rotate);
        break;
    case Qt::Key_Down:
        blockMove(MoveDown);
        break;
    case Qt::Key_Left:
        blockMove(MoveLeft);
        break;
    case Qt::Key_Right:
        blockMove(MoveRight);
        break;
    case Qt::Key_Space:
        blockMove(DropDown);
        break;
    default:
        break;
    }
}
